//
// OpenTemplate
// Copyright (c) 2006
// by OpenArrow Software ( http://www.openarrow.com )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System;
using System.CodeDom;
using OpenArrow.Templating.Parsing;
using OpenArrow.Templating.Properties;

namespace OpenArrow.Templating.Directives
{
    /// <summary>
    /// Directive that specifies core information about the template generation
    /// </summary>
    [Directive("Template")]
    public class TemplateDirective : DirectiveBase
    {
        private const string DEFAULT_NAMESPACE = "Templates";
        private const string DEFAULT_INHERITS = "OpenArrow.Templating.Template";

        #region Private Fields

        private string className;
        private string @namespace;
        private bool partial;
        private string inherits;
        private string language;
        private string outputType;
        private string codeFile;
        private bool xmlSerializable;

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets or sets the name of the class that the template builder will create
        /// </summary>
        public string ClassName
        {
            get { return className; }
            set { className = value; }
        }

        /// <summary>
        /// Gets or sets the namespace that the class will be located in
        /// </summary>
        public string Namespace
        {
            get { return @namespace; }
            set { @namespace = value; }
        }

        /// <summary>
        /// Gets or sets a boolean determining if the resulting class should be a partial class
        /// </summary>
        public bool Partial
        {
            get { return partial; }
            set { partial = value; }
        }

        /// <summary>
        /// Gets or sets the full name of the type that this template inherits from
        /// </summary>
        public string Inherits
        {
            get { return inherits; }
            set { inherits = value; }
        }

        /// <summary>
        /// Gets or sets the language that this template is written in
        /// </summary>
        public string Language
        {
            get { return language; }
            set { language = value; }
        }

        /// <summary>
        /// Gets or sets the type of the output that the template produces
        /// </summary>
        public string OutputType
        {
            get { return outputType; }
            set { outputType = value; }
        }

        /// <summary>
        /// Gets or sets the path to the code file associated with this template
        /// </summary>
        public string CodeFile
        {
            get { return codeFile; }
            set { codeFile = value; }
        }

        /// <summary>
        /// Gets or sets a boolean indicating if the generated class should support XmlSerialization
        /// </summary>
        public bool XmlSerializable
        {
            get { return xmlSerializable; }
            set { xmlSerializable = value; }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Executes the Directive
        /// </summary>
        /// <param name="context">Context information for the execution of the directive</param>
        /// <exception cref="OpenArrow.Templating.ActionProblemsException">A large number of errors occurred in the operation and it had to be aborted</exception>
        public override void Execute(DirectiveContext context)
        {
            base.Execute(context);
            using (context.Reporter.StartTask(String.Format(Resources.Task_ExecutingDirective, "Template")))
            {
                if (String.IsNullOrEmpty(ClassName))
                {
                    context.Problems.Add(Problem.Error_NoClassNameSpecified(LineNumber));
                    context.Problems.Throw();
                }

                if (String.IsNullOrEmpty(Namespace))
                {
                    context.Problems.Add(Problem.Warning_NoNamespaceSpecified(DEFAULT_NAMESPACE, LineNumber));
                    Namespace = DEFAULT_NAMESPACE;
                }

                if (String.IsNullOrEmpty(Inherits))
                    Inherits = DEFAULT_INHERITS;

                if (String.IsNullOrEmpty(Language))
                {
                    context.Problems.Add(Problem.Error_NoLanguageSpecified(LineNumber));
                    context.Problems.Throw();
                }

                context.TemplateType.Name = ClassName;
                context.TemplateType.IsPartial = Partial;
                CodeNamespace codeNamespace = new CodeNamespace(this.Namespace);
                codeNamespace.Types.Add(context.TemplateType);
                context.TemplateCompileUnit.Namespaces.Add(codeNamespace);
            }
        }
        #endregion
    }
}
